/**
   在这个之前需要先理解几个概念：
   1.栈和堆
   堆  -放不固定大小的，必须有指针指向这里，指针放在栈内
   栈  -放固定大小（需要在编译的时候就已经知道的...?)  ,filo(后进先出) 
   
   2.作用域结束会自动释放堆内容. 但这个不是像其它语言那样好理解。在其它语言中，在作用域内是一直有效的。
   
   3.最基本的原则
     每个值都有一个所有者，且任何时候只有一个使用者，当所有者离开作用域之后，持有的值被释放.
    
 */
 fn main(){
	let s1=String::from("锦绣中华");
	// 如果按照以下这个方式编写，那么会错误的
	// 这是因为，这种方式下，s2的指针指向s1指向的堆，同时会把s1标记为无效 -- 这是基于rust的原则
	/*
	let s2=s1;
	println!("{}",s1); 
	编译错误如下：
	let s1=String::from("锦绣中华");
	   |         -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
	12 |     let s2=s1;
	   |            -- value moved here
	13 |     println!("{}",s1);
	   |                   ^^ value borrowed here after move
	*/
	
	// 以下一段代码则是对的
	// 这是因为s2的值是赋值过来的，复制的是堆的内存，所以s1还占有原来的值
	let s2=s1.clone();
	println!("s1={},s2={}",s1,s2); 
	//需要特别注意的是：println!并不会夺取所有权，即使你传递参数的时候没有带&
	
 }
 